<template>
  <div class="rightMian">
    <div class="el-title">
      <p>
        共发现 <span>{{ totalProblem }}</span> 处问题
      </p>
    </div>
    <div class="container">
      <div class="tabs">
        <div
          class="tab"
          :class="{ active: activeTab === index }"
          v-for="(tab, index) in tabs"
          :key="index"
          @click="handleTab(index)"
          :style="{ marginRight: index < tabs.length - 1 ? '15px' : '0' }"
        >
          <p>{{ tab.title }}</p>
          <p class="count">{{ tab.count }}</p>
        </div>
      </div>
      <div class="problem-content fierce scrollbar">
        <NotData v-show="notDataStatus" />
        <!-- 合规 -->
        <template v-if="activeTab === 0 && !notDataStatus">
          <div
            v-for="(obj, index) in tabs[activeTab].list"
            :key="index"
            @click="handleCompliance({ data: obj, index })"
            :class="['compliance-item', complianceActive === index ? 'active' : '']"
          >
            <div v-if="Array.isArray(obj.hgxDetail)">
              <p class="title">{{ obj.titleName }} - {{ obj.indicatorName }}</p>
              <p v-for="(item, j) in obj.hgxDetail" :class="[j === 0 ? 'block-text' : '']">
                {{ item.name }}
                <!--  :class="item.position === 1 ? 'count' : ''" -->
                <span :class="errorClass(item, obj)">{{ item.value }}</span>
                &nbsp;&nbsp;
              </p>
              <p class="block-text">{{ obj.citation }}</p>
            </div>
          </div>
        </template>
        <!-- 一致性 -->
        <template v-if="activeTab === 1  && !notDataStatus">
          <div
            class="consistency-item"
            v-for="(item, index) in tabs[activeTab].list"
            :key="index"
            :class="[consistencyActive === index ? 'active' : '']"
          >
            <template v-if="Array.isArray(item.children) && item.children.length">
              <h6>
                {{ item.type }}
              </h6>
              <div class="min-title">
                全文共 <span>{{ getAllConsistencyNum(item.children) }}</span> 处
              </div>
              <div
                class="text"
                style="font-size: 14px"
                v-for="(a, j) in item?.children"
                :key="j"
                @click="handleConsistency({ name: a.name, key: item.type, index, number: a.number })"
              >
                <p>{{ a.name }}</p>
                <span>{{ a.number }} <i>处</i></span>
              </div>
            </template>
          </div>
        </template>
        <!-- 计算问题 -->
        <template v-if="activeTab === 2 && !notDataStatus">
          <div
            v-for="(item, index) in tabs[activeTab].list"
            :key="index"
            @click="handleProblem(item, index)"
            :class="['problem-item', problemActive === index ? 'active' : '']"
          >
            <p style="font-weight: bold">{{ item.type }}</p>
            <p>
              计算公式<span>{{ item.expression }}</span>
            </p>
            <p>
              <!--  item.actual -->
              正确数据<span>{{ setActual(item) }}</span>
            </p>
            <p>
              错误数据<span style="color: red">{{ item.errorStr }}</span>
            </p>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { defineProps, watch, ref, computed, onMounted, nextTick } from 'vue'
import NotData from '@/components/business/NotData/index.vue'
import { chatAiDocStart, getFileSSE } from '@/api/pengwei/fileManagement'
import { ruleType } from '@/utils/const'
import { isObject, isEmpty, isFunction, cloneDeep } from 'lodash-es'
import { getMsg } from '@/mockData/pengwei'
import {
  compareString,
  extractOuterParentheses,
  extractTrailingUnit,
  getRowanTable,
  mergeData,
  removeParenthesesContent,
  removeSpaces,
  scrollIntoView,
  splitMergedCells,
  tableToObjectArray,
} from '@/utils/tool'
import { ElMessage } from 'element-plus'
import fileManagement from '@/stores/fileManagement'

const fileManagementStore = fileManagement()
const tabs: any = ref([
  { title: '合规问题', count: 0, list: [] },
  { title: '一致性问题', count: 0, obj: {} },
  { title: '计数问题', count: 0, list: [] },
])
const errorDom: any[] = []
const activeTab = ref(0)
const complianceActive = ref(-1)
const consistencyActive = ref(-1)
const problemActive = ref(-1)
let docxWrapper: Element | any = null
let eventSource: EventSource | null = null
let consistencyErrorData: any = {}
let docxMenuList: any = []

const notDataStatus = computed(() => {
  const currentList = tabs.value[activeTab.value]?.list
  if (Array.isArray(currentList) && currentList.length) {
    return false
  }
  return true
})
const totalProblem = computed(() => {
  return tabs.value.reduce((sum: any, person: any) => sum + person.count, 0)
})

function handleTab(index: number) {
  activeTab.value = index
  complianceActive.value = -1
  consistencyActive.value = -1
  problemActive.value = -1
}

function errorClass(item: any, obj: any) {
  if (obj.type === ruleType.hgxApf) return ''
  let className = ''
  const target = obj.hgxDetail.find((o: any) => o.position === 3)
  if (item.position === 1) {
    if (item.value > target.value || !item.ifMatch) {
      className = 'count'
    }
  } else {
    if (!item.ifMatch) {
      className = 'count'
    }
  }

  return className
}

function setActual({ actual, errorStr }: any) {
  const res = extractTrailingUnit('' + errorStr)
  return actual + res
}

// 合规错误跳转
function handleCompliance({ data, index }: any) {
  // obj.hgxDetail, index, obj.type || '', obj.citation, obj
  // array: any = [], index: number, type: string, citation: string, currentData: any
  console.log(data, 'item-data')

  const { hgxDetail = [], citation, type, indicatorName, titleName } = data
  const obj: any = {}

  // 存储文件中的原始数据
  const judgeData: any = {
    //指标值
    projectMetric: {},
    // 引导值
    steer: {},
    // 限额值
    restraint: {},
    // 平均值
    mean: {},
  }
  hgxDetail.forEach((a: any) => {
    a.equal = a.value === a.ruleValue
    switch (a.position) {
      // 指标
      case 1:
        obj.projectMetricKey = a.value // 指标值
        obj.projectMetricName = a.name // 名称
        judgeData.projectMetric = a
        break
      case 2:
        obj.steerKey = a.value // 引导值
        judgeData.steer = a
        break
      case 3:
        obj.restraintKey = a.value // 限额值
        judgeData.restraint = a
        break
      case 4:
        obj.meanValue = a.value // 平均值
        judgeData.mean = a
        break
    }
  })
  const { steerKey, restraintKey, meanValue, projectMetricKey } = obj
  getDocxWrapper()
  removeClass()
  // // 先从table中匹配
  const table: any = docxWrapper.querySelectorAll('table') || []
  let matchText = ''
  function addErrorData(el: any) {
    el.classList.add('docx-error-compliance-box')
    scrollIntoView(el)
    errorDom.push(el)
    matchText += el.innerText
  }
  // APF数据
  if (type === ruleType.hgxApf) {
    console.log('APF')
    let currentTable = null
    for (let i = 0; i < table.length; i++) {
      const t: any = table[i]
      if (t.innerText.includes(steerKey)) {
        const currentList = tableToObjectArray(t)
        console.log(t, '当前表格')
        currentTable = t
        for (let j = 0; j < currentList.length; j++) {
          const o = currentList[j]
          let signList = []
          for (const key in o) {
            const v: any = o[key]
            if (key !== 'el' && v) {
              // 规则值必须相等
              if (compareString(v, steerKey)) {
                signList.push({
                  value: steerKey,
                  el: o.el,
                })
              }
              // 指标值包含
              if (v.includes(projectMetricKey)) {
                signList.push({
                  value: projectMetricKey,
                  el: o.el,
                })
              }
            }
          }
          if (signList.length >= 2) {
            const tr: any = signList[0].el
            tr.classList.add('docx-error-compliance-box')
            scrollIntoView(tr)
            errorDom.push(tr)
            matchText += tr.innerText
          }
        }
      }
    }
  } else {
    // 正常数据
    let tableList = []
    // 处理引用内容不和源文件中的匹配
    const newCitation = citation.replace('引自', '').match(/《([^》]+)》/)[1]
    // 处理标题
    let newIndicatorName = indicatorName
    let comprehensiveElectricityConsumption = false
    let title = removeParenthesesContent(titleName)
    if (indicatorName.includes('（') && indicatorName.includes('）') && indicatorName.includes('-')) {
      newIndicatorName = extractOuterParentheses(indicatorName).replace('-', '') || indicatorName
      comprehensiveElectricityConsumption = true
    }
    for (let i = 0; i < table.length; i++) {
      const t = table[i]
      // 取出包含特定文本的表格
      if (
        removeSpaces(t.innerText).includes(removeSpaces(newCitation)) &&
        removeSpaces(t.innerText).includes(removeSpaces(newIndicatorName))
      ) {
        // console.log(t, '当前表格')
        // 如果是正常数据，则需要判断标题是否包含
        if (!comprehensiveElectricityConsumption && t.innerText.includes(title)) {
          // console.log(t, '当前表格2')
          tableList.push(t)
          break
        }
        tableList.push(t)
      }
    }
    if (tableList.length) {
      let currentTr = null
      let currentTable = null
      for (let i = 0; i < tableList.length; i++) {
        const table = tableList[i]
        const rowList = table.rows
        const tableText = table.innerText
        if (
          removeSpaces(tableText).includes(removeSpaces(newCitation)) &&
          removeSpaces(tableText).includes(removeSpaces(newIndicatorName)) &&
          removeSpaces(tableText).includes(removeSpaces(projectMetricKey))
        ) {
          currentTable = table
        }
        for (let i = 0; i < rowList.length; i++) {
          const tr = rowList[i]
          let isIncludes = false
          if (
            tr.innerText.includes(newIndicatorName) &&
            tr.innerText.includes(projectMetricKey) &&
            tr.innerText.includes(steerKey) &&
            tr.innerText.includes(restraintKey) &&
            tr.innerText.includes(meanValue)
          ) {
            // 正常文档数据
            // console.log(tr, '---123')
            isIncludes = true
          } else if (comprehensiveElectricityConsumption && tr.innerText.includes(projectMetricKey)) {
            // 单位建筑面积年综合能耗
            isIncludes = true
          }
          if (isIncludes) {
            currentTr = tr
            // console.log(currentTable, tr, '当前的行', isIncludes, comprehensiveElectricityConsumption)
            // 高亮文本
            const tdList = tr.cells
            for (let j = 0; j < tdList.length; j++) {
              const td = tdList[j]
              const text = td.innerText
              if (compareString(text, projectMetricKey)) {
                if (!judgeData.projectMetric.ifMatch || projectMetricKey > restraintKey) {
                  addErrorData(td)
                }
              }
              if (compareString(text, steerKey) && !judgeData.steer.ifMatch) {
                addErrorData(td)
              }
              if (compareString(text, restraintKey) && !judgeData.restraint.ifMatch) {
                addErrorData(td)
              }
              if (compareString(text, meanValue) && !judgeData.mean.ifMatch) {
                addErrorData(td)
              }
            }
          }
        }
      }
      if (!matchText && currentTable) {
        // // 说明找不到当前行，查找是否是合并了单元格
        console.log(currentTr, 'currentTr')
        const splitTable = splitMergedCells(currentTable)
        const hgxObj = {
          steerKey,
          meanValue,
          projectMetricKey,
          indicatorName,
        }
        const { rowspanTr, splitTr }: any = getRowanTable({ mergeTable: currentTable, splitTable, hgxData: hgxObj })
        if (rowspanTr && splitTr) {
          const splitTd = splitTr.cells
          const rowspanTd = rowspanTr.cells
          let projectText = null
          let steerText = null
          let restraintText = null
          let meanText = null

          for (let i = 0; i < splitTd.length; i++) {
            const td = splitTd[i]
            const text = td.innerText
            // 指标值
            if (!judgeData.projectMetric.ifMatch || projectMetricKey > restraintKey) {
              if (compareString(text, projectMetricKey)) {
                addErrorData(td)
              } else {
                projectText = projectMetricKey
              }
            }
            // 引导值
            if (!judgeData.steer.ifMatch) {
              if (compareString(text, steerKey)) {
                addErrorData(td)
              } else {
                steerText = steerKey
              }
            }

            // 限额值
            if (!judgeData.restraint.ifMatch) {
              if (compareString(text, restraintKey)) {
                addErrorData(td)
              } else {
                restraintText = restraintKey
              }
            }

            // 平均值
            if (!judgeData.mean.ifMatch) {
              if (compareString(text, meanValue)) {
                addErrorData(td)
              } else {
                meanText = meanValue
              }
            }
          }

          // 如果当前的tr中没有找到 则需要去合并他的行查找
          for (let i = 0; i < rowspanTd.length; i++) {
            const td = rowspanTd[i]
            const text = td.innerText
            if (td.rowSpan < 2 || !text) {
              continue
            }
            if (compareString(text, projectText)) {
              addErrorData(td)
            }
            if (compareString(text, steerText)) {
              addErrorData(td)
            }
            if (compareString(text, restraintText)) {
              addErrorData(td)
            }
            if (compareString(text, meanText)) {
              addErrorData(td)
            }
          }
          // console.log(splitTd, 'splitTd')
          // console.log(rowspanTd, 'rowspanTd')
          // console.log(projectText, steerText, '------');
          // console.log(restraintText, meanText, '----2--');
        }
      }
    }
  }

  if (matchText) {
    complianceActive.value = index
  } else {
    infoMsg()
  }
  // complianceActive.value = index
  // if(!matchText) {
  //   scrollIntoView(currentTable)
  // }
}

// 一致性错误跳转
function handleConsistency({ name, key, index, number }: any) {
  getDocxWrapper()
  removeClass()
  let errorList = []
  let matchText = ''
  // console.log(name, key, 'name, key')

  // 初始化每一个item对象用来存储对应的dom并记录点击的索引值
  if (!consistencyErrorData[key]) {
    consistencyErrorData[key] = {
      index: -1,
      elList: [],
    }
  }
  consistencyErrorData[key].elList.length = 0

  // 从p标签中匹配文本
  const pList: any = docxWrapper.querySelectorAll('p') || []
  for (let i = 0; i < pList.length; i++) {
    const p = pList[i]
    if (!removeSpaces(p.innerText)) {
      continue
    }
    if (!p.innerText.includes(name)) {
      continue
    }
    errorList.push(p)
    matchText += p.innerText
  }

  errorList.forEach((p, j) => {
    // 处理匹配到的文本数量大于解析出来的数量
    if (j <= number - 1) {
      // 保存匹配到的dom并增加高亮class
      consistencyErrorData[key].elList.push(p)
      p.classList.add('docx-error-consistency-box')
      errorDom.push(p)
    }
  })

  if (matchText) {
    consistencyActive.value = index
  } else {
    infoMsg()
    return
  }

  // 滚动到指定dom的位置
  const currentData = consistencyErrorData[key]
  currentData.index += 1
  if (currentData.index > currentData.elList.length - 1) {
    currentData.index = 0
  }
  if (currentData.index > number) {
    currentData.index = number - 1
  }
  const currentEl = currentData.elList[currentData.index]

  scrollIntoView(currentEl)
  if (!currentEl) {
    console.error(currentData, 'currentData')
  }
}

function infoMsg() {
  ElMessage.info('没有匹配到文本')
}

// 计算问题错误跳转
function handleProblem(item: any, index: number) {
  getDocxWrapper()
  removeClass()
  let matchText = ''
  // 先从table中匹配
  const table: any = docxWrapper.querySelectorAll('table') || []
  for (let i = 0; i < table.length; i++) {
    const t: any = table[i]
    const pList = t.querySelectorAll('p')
    for (let j = 0; j < pList.length; j++) {
      const p = pList[j]
      if (p?.innerText.trim() === (item.errorStr + '').trim()) {
        // if (p?.innerText.includes(item.errorStr)) {
        // console.log(p, '====ppp');
        p.classList.add('docx-error-problem-box')
        scrollIntoView(p)
        errorDom.push(p)
        matchText = p.innerText
      }
    }
  }

  if (matchText) {
    problemActive.value = index
  } else {
    infoMsg()
    return
  }
}

function removeClass() {
  for (let i = 0; i < errorDom.length; i++) {
    const e = errorDom[i]
    if (e.classList && e.classList.remove) {
      e.classList.remove('docx-error-problem-box')
      e.classList.remove('docx-error-consistency-box')
      e.classList.remove('docx-error-compliance-box')
    }
  }
}

function getDocxWrapper() {
  if (!docxWrapper) {
    docxWrapper = document.querySelector('.docx-wrapper')
  }
}

function getAllConsistencyNum(list: any[]) {
  return list?.reduce((sum, person) => sum + person.number, 0)
}

function getDocxData(fileName: string) {
  if (!!eventSource) {
    eventSource.close()
  }
  fileManagementStore.updatedSseLoadText('开始解析...')
  errorDom.length = 0
  consistencyErrorData = {}
  docxWrapper = null
  tabs.value.forEach((t: any) => {
    if (Array.isArray(t.list)) {
      t.list.length = 0
    }
    if (t.obj) {
      t.obj = {}
    }
    t.count = 0
  })
  let consistencyList: any = []
  let msgList: any[] = []
  // 暂时屏蔽
  // getFileSSE({
  //   fileName: fileName,
  //   onMessage(msg, evtSource: EventSource) {
  //     // console.log(msg, 'msg', evtSource)
  //     if (!msg) return
  //     if (!!evtSource) {
  //       eventSource = evtSource
  //     }
  //     formatDocxData(msg)
  //   },
  //   onEnd() {
  //   fileManagementStore.updatedSseLoadText('AI解析完成')
  //     console.log('接收完了')
  //   },
  // })

  // //  模拟数据--start
  let index = 0
  setInterval(() => {
    const msg = getMsg(index)
    msg && formatDocxData(msg)
    index += 1
  }, 100)
  // mock--end--

  // 测试接口
  // chatAiDocStart({
  //   onMessage(msg, evtSource: EventSource){
  //     console.log(msg, 'msg-测试接口');
  //     if (!msg) return
  //     if (!!evtSource) {
  //       eventSource = evtSource
  //     }
  //     formatDocxData(msg)
  //   },
  //   onEnd() {
  //     console.log('接收完了')
  //   },
  // })
  // --end
  function formatDocxData(msg: any) {
    if (!msg.ruleType) {
      return
    }
    msgList.push(msg)
    console.log(msgList, 'msgList')
    // 判断解析状态
    switch (msg.ruleType) {
      case ruleType.start:
        break
      case ruleType.end:
        fileManagementStore.updatedSseLoadText('AI解析完成')
        break
    }

    // 合规性
    if (msg.ruleType === ruleType.ruleHgx) {
      tabs.value[0].list.push(...msg.result.result)
      tabs.value[0].count = tabs.value[0].list.length
      // console.log(tabs.value[0].list, '合规性数组')
    }
    // 一致性
    if (msg.ruleType === ruleType.ruleYzx) {
      consistencyList.push(...msg.result?.result)
      const mergeList = mergeData(cloneDeep(consistencyList))
      tabs.value[1].list = mergeList
      // let count = 0
      // mergeList.forEach((m: any) => {
      //   Array.isArray(m?.children) &&
      //     m?.children.forEach((c: any) => {
      //       count += c.number
      //     })
      // })
      tabs.value[1].count = mergeList.length
    }

    // // 计算问题
    if (msg.ruleType === ruleType.ruleJs) {
      tabs.value[2].list.push(...msg.result?.result)
      tabs.value[2].count = tabs.value[2].list.length
      // console.log(tabs.value[2].list, 'tabs.value[2].list')
    }
  }
}

defineExpose({
  getDocxData,
})
</script>

<style scoped lang="scss">
.rightMian {
  height: 100%;
  overflow-y: auto;
  padding-right: 10px;
  .el-title {
    font-weight: bold;
    display: flex;
    justify-content: space-between;
    height: 40px;
    display: flex;
    align-items: center;
    color: #666;
    font-size: 14px;
    font-weight: normal;
    span {
      font-size: 18px;
      color: rgb(233, 7, 26);
      font-weight: bold;
      &.sse-text {
        font-weight: normal;
        font-size: 14px;
        color: #4466f0;
      }
    }
  }
}

.el-table {
  width: 100%;
  height: calc(100% - 50px); /* 减去分页组件的高度 */
}

.dialogue-item {
  margin-bottom: 10px;
}

::v-deep .highlight-row {
  background-color: #ffff99; /* 高亮颜色 */
}
.container {
  margin: 0 auto;
}

.tabs {
  display: flex;
  justify-content: space-between;
  padding: 10px 10px 10px 0;
}

.tab {
  flex: 1;
  text-align: center;
  // padding: 10px;
  padding-left: 0 !important;
  padding-bottom: 0 !important;
  cursor: pointer;
  transition: background-color 0.3s;
  font-size: 14px;
  // font-weight: bold;
  background-color: #f3f4f4;
  border-radius: 4px;
  // border: 2px solid transparent;

  p {
    line-height: 30px;
  }
  .count {
    font-size: 16px;
    color: rgb(233, 7, 26);
    font-weight: bold;
  }
}

.tab.active {
  background-color: rgb(255 235 235);
  color: rgb(233, 7, 26);
  // border: 2px solid rgb(95, 151, 165);
}

.problem-content {
  margin-top: 20px;
  padding: 10px 10px 10px 0;
  height: calc(100vh - 254px);
  font-size: 14px;
  overflow: hidden;
  overflow-y: auto;
  position: relative;
  .compliance-item,
  .consistency-item,
  .problem-item {
    padding: 10px;
    border: 1px solid #f5f5f5;
    margin-bottom: 10px;
    cursor: pointer;
    &.active {
      border-color: #4466f0;
      background: rgba(68, 102, 240, 0.2);
    }
    h6,
    p,
    span {
      word-break: break-all;
    }
  }
  .compliance-item {
    * {
      pointer-events: none !important;
    }
    .title {
      margin-bottom: 10px !important;
      color: #333;
      font-size: 14px;
      font-weight: bold;
    }
    p {
      margin: 0;
      margin-bottom: -8px;
      line-height: 22px;
      &.block-text {
        display: block;
      }
      span {
        display: block;
      }
      .count {
        font-size: 18px;
        color: rgb(233, 7, 26);
        font-weight: bold;
      }
    }
  }
  .consistency-item {
    cursor: default;
    h6 {
      color: #333;
      font-size: 14px;
    }
    .min-title {
      color: #666;
      font-size: 14px;
      margin-top: 4px;
      span {
        color: #4466f0;
        font-size: 14px;
        font-weight: bold;
      }
    }
    .text {
      display: flex;
      justify-content: space-between;
      align-items: center;
      color: #333;
      margin: 0;
      line-height: 28px;
      cursor: pointer;
      p {
        max-width: 75%;
      }
      i {
        color: #666;
        font-style: normal;
      }
    }
  }
  .problem-item {
    p {
      color: #333;
      margin-bottom: 10px;
      display: flex;
      line-height: 20px;
      flex-direction: column;
      span {
        color: #666;
      }
    }
  }
}
</style>
<style lang="scss">
.docx-error-compliance-box {
  * {
    color: red !important;
  }
}
.docx-error-consistency-box {
  * {
    color: red !important;
  }
}
.docx-error-problem-box {
  * {
    color: red !important;
  }
}
</style>
